package com.stek.spec;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.Camera;
import android.hardware.Sensor;
import android.os.AsyncTask;
import android.os.BatteryManager;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ListView;
import android.widget.TextView;

import com.stek.R;
import com.stek.base.BaseFragment;
import com.stek.utils.AppUtils;
import com.stek.utils.Utils;
import com.stek.utils.Utils.CPU;
import com.stek.utils.Utils.Screen.ScreenInfo;
import com.stek.utils.Utils.Telephony.SimInfo;

public class SpecFragment extends BaseFragment {
	// ============================================================
	private String type;
	private View rootView;
	private BroadcastReceiver mBatteryReceiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {
			// TODO Auto-generated method stub
			String action = intent.getAction();
			if (Intent.ACTION_BATTERY_CHANGED.equals(action)) {
				loadBattery(context, intent, rootView);
			}

		}
	};

	// ============================================================
	public static SpecFragment newInstance(String type) {
		SpecFragment fragment = new SpecFragment();
		Bundle bundle = new Bundle();
		bundle.putString("type", type);
		fragment.setArguments(bundle);
		return fragment;
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		type = getArguments().getString("type");
		super.onCreate(savedInstanceState);
	}

	@Override
	public View onCreateView(LayoutInflater inflater,
			@Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
		rootView = inflater.inflate(R.layout.fragment_list, container, false);
		if (getString(R.string.telephony).equals(type)) {
			loadTelephony(rootView);
		} else if (getString(R.string.display).equals(type)) {
			loadDisplay(rootView);
		} else if (getString(R.string.memory).equals(type)) {
			loadMemory(rootView);
		} else if (getString(R.string.data).equals(type)) {
			loadData(rootView);
		} else if (getString(R.string.camera).equals(type)) {
			loadCamera(rootView);
		} else if (getString(R.string.feature).equals(type)) {
			loadChipSet(rootView);
		} else if (getString(R.string.sensor).equals(type)) {
			loadSensor(rootView);
		} else if (getString(R.string.battery).equals(type)) {
			getActivity().getApplicationContext().registerReceiver(
					mBatteryReceiver,
					new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
		}

		return rootView;
	}

	@Override
	public void onDestroyView() {
		try {
			getActivity().getApplicationContext().unregisterReceiver(
					mBatteryReceiver);
		} catch (Exception e) {
		}
		super.onDestroyView();
	}

	private void loadTelephony(View view) {
		boolean hasSIM = Utils.Telephony.hasTelephony(getActivity()
				.getApplicationContext());
		ListView lv = (ListView) view
				.findViewWithTag(getString(R.string.tag_list));
		ArrayList<Info> infos = new ArrayList<Info>();
		infos.add(new Info(getString(R.string._2g_network), Utils.Telephony
				.getPhoneType(getActivity().getApplicationContext())));
		infos.add(new Info(getString(R.string._3g_network), Utils.Telephony
				.getNetworkType(getActivity().getApplicationContext())));
		if (!hasSIM) {
			infos.add(new Info(getString(R.string.sim), getString(R.string.n_a)));
			return;
		}
		SimInfo simInfo1 = Utils.Telephony.getSIM1(getActivity()
				.getApplicationContext());
		infos.add(new Info(getString(R.string.imei), simInfo1.deviceId));
		if (!TextUtils.isEmpty(simInfo1.serial)) {
			infos.add(new Info(getString(R.string.serial_), simInfo1.serial));
		}
		if (!TextUtils.isEmpty(simInfo1.number)) {
			infos.add(new Info(getString(R.string.number_), simInfo1.number));
		}
		SimInfo simInfo2 = Utils.Telephony.getSIM2(getActivity()
				.getApplicationContext());
		if (!TextUtils.isEmpty(simInfo2.deviceId)) {
			infos.add(new Info(getString(R.string.imei_slot_2_),
					simInfo2.deviceId));
		}
		if (!TextUtils.isEmpty(simInfo2.serial)) {
			infos.add(new Info(getString(R.string.serial_slot_2_),
					simInfo2.serial));
		}
		if (!TextUtils.isEmpty(simInfo2.number)) {
			infos.add(new Info(getString(R.string.number_slot_2_),
					simInfo2.number));
		}
		lv.setAdapter(new InfoAdapter(getActivity().getApplicationContext(),
				infos));

	}

	private void loadDisplay(View view) {

		ListView lv = (ListView) view
				.findViewWithTag(getString(R.string.tag_list));
		ScreenInfo screenInfo = Utils.Screen.getScreenInfo(getActivity()
				.getApplicationContext());
		String resolution = String.format("%s x %s pixels", screenInfo.width,
				screenInfo.height);
		ArrayList<Info> infos = new ArrayList<Info>();
		infos.add(new Info(getString(R.string.size), String.format(
				" %.1f inches", screenInfo.inches)));
		infos.add(new Info(getString(R.string.resolution), resolution));
		infos.add(new Info(getString(R.string.density), screenInfo.densityDpi
				+ " dpi"));
		infos.add(new Info(getString(R.string.multitouch),
				Utils.Hardware.hasMultiTouch(getActivity()
						.getApplicationContext()) ? getString(R.string.yes)
						: getString(R.string.n_a)));
		lv.setAdapter(new InfoAdapter(getActivity().getApplicationContext(),
				infos));

	}

	@SuppressLint("NewApi")
	private void loadMemory(View view) {

		ListView lv = (ListView) view
				.findViewWithTag(getString(R.string.tag_list));

		ArrayList<Info> infos = new ArrayList<Info>();
		infos.add(new Info(getString(R.string.total_ram), AppUtils
				.convertSizeIntoString(Utils.Memory
						.getTotalMemory(getActivity().getApplicationContext()))));
		infos.add(new Info(getString(R.string.free_ram), AppUtils
				.convertSizeIntoString(Utils.Memory
						.getAvailableMemory(getActivity()
								.getApplicationContext()))));
		infos.add(new Info(getString(R.string.total_internal), AppUtils
				.convertSizeIntoString(Utils.Memory
						.getTotalInternalMemorySize())));
		infos.add(new Info(getString(R.string.free_internal), AppUtils
				.convertSizeIntoString(Utils.Memory
						.getAvailableInternalMemorySize())));
		if (Utils.Memory.isExternalMemoryAvailable()) {
			infos.add(new Info(getString(R.string.total_external), AppUtils
					.convertSizeIntoString(Utils.Memory
							.getTotalExternalMemorySize())));
			infos.add(new Info(getString(R.string.free_external), AppUtils
					.convertSizeIntoString(Utils.Memory
							.getAvailableExternalMemorySize())));
		}
		lv.setAdapter(new InfoAdapter(getActivity().getApplicationContext(),
				infos));

	}

	private void loadData(View view) {

		ListView lv = (ListView) view
				.findViewWithTag(getString(R.string.tag_list));
		ArrayList<Info> infos = new ArrayList<Info>();
		String wifiString = "";
		if (Utils.WIFI.hasWifi(getActivity().getApplicationContext())) {
			wifiString = getActivity().getString(R.string.wifi);
		}
		if (Utils.WIFI.hasWifiDirect(getActivity().getApplicationContext())) {
			wifiString += ", " + getActivity().getString(R.string.wifi_direct);
		}
		if (TextUtils.isEmpty(wifiString)) {
			wifiString = getActivity().getString(R.string.n_a);
		}
		infos.add(new Info(getString(R.string.wlan), wifiString));
		infos.add(new Info(getString(R.string.bluetooth),
				Utils.Bluetooth.hasBluetooth(getActivity()
						.getApplicationContext()) ? getString(R.string.yes)
						: getString(R.string.n_a)));
		infos.add(new Info(
				getString(R.string.gps),
				Utils.GPS.hasLocationGPS(getActivity().getApplicationContext()) ? getString(R.string.yes)
						: getString(R.string.n_a)));
		infos.add(new Info(
				getString(R.string.usb),
				Utils.Hardware.hasUSB(getActivity().getApplicationContext()) ? getString(R.string.yes)
						: getString(R.string.n_a)));
		lv.setAdapter(new InfoAdapter(getActivity().getApplicationContext(),
				infos));

	}

	private void loadCamera(final View view) {
		final Context context = getActivity().getApplicationContext();
		final WeakReference<Fragment> weakReference = new WeakReference<Fragment>(
				SpecFragment.this);
		final ArrayList<Info> infos = new ArrayList<SpecFragment.Info>();
		final ListView lv = (ListView) view.findViewWithTag(getActivity()
				.getString(R.string.tag_list));
		lv.setAdapter(new InfoAdapter(context, infos));
		new AsyncTask<Void, Void, String>() {

			private boolean isContext() {
				return weakReference != null && weakReference.get() != null;
			}

			@Override
			protected String doInBackground(Void... params) {
				if (isContext()
						&& !Utils.CameraHardware.hasCameraFront(getActivity())) {
					return null;
				} else {
					Camera frontCamera = Utils.CameraHardware.getFrontCamera();
					String frontInfo = String.format("%s", Utils.CameraHardware
							.getCameraResolutionInMP(frontCamera));
					Utils.CameraHardware.releaseCamera(frontCamera);
					return frontInfo;
				}

			}

			@Override
			protected void onPostExecute(String info) {
				if (TextUtils.isEmpty(info)) {
					info = getString(R.string.n_a);
				}
				if (isContext()) {
					infos.add(new Info(getString(R.string.front), info));
					((BaseAdapter) lv.getAdapter()).notifyDataSetChanged();
				}

				super.onPostExecute(info);
			}
		}.execute();
		new AsyncTask<Void, Void, String>() {

			private boolean isContext() {
				return weakReference != null && weakReference.get() != null;
			}

			@Override
			protected String doInBackground(Void... params) {
				if (isContext()
						&& !Utils.CameraHardware.hasCameraBack(getActivity())) {
					return null;
				} else {
					Camera backCamera = Utils.CameraHardware.getBackCamera();
					String backInfo = String.format("%s", Utils.CameraHardware
							.getCameraResolutionInMP(backCamera));
					Utils.CameraHardware.releaseCamera(backCamera);
					return backInfo;

				}
			}

			@Override
			protected void onPostExecute(String info) {

				if (TextUtils.isEmpty(info)) {
					info = getString(R.string.n_a);
				}
				if (isContext()) {
					infos.add(new Info(getString(R.string.back), info));
					((BaseAdapter) lv.getAdapter()).notifyDataSetChanged();
				}

				super.onPostExecute(info);
			}
		}.execute();
		new AsyncTask<Void, Void, String>() {

			private boolean isContext() {
				return weakReference != null && weakReference.get() != null;
			}

			@Override
			protected String doInBackground(Void... params) {
				ArrayList<Info> infos = new ArrayList<Info>();
				String video = null;
				if (isContext()
						&& Utils.CameraHardware.hasCameraFront(getActivity())) {
					Camera frontCamera = Utils.CameraHardware.getFrontCamera();
					video = Utils.CameraHardware.getVideoResolution(
							getActivity(), frontCamera);
					Utils.CameraHardware.releaseCamera(frontCamera);
					return video;

				}
				if (isContext()
						&& Utils.CameraHardware.hasCameraBack(getActivity())) {
					infos.add(new Info(getString(R.string.back),
							getString(R.string.n_a)));
					Camera backCamera = Utils.CameraHardware.getBackCamera();
					video = Utils.CameraHardware.getVideoResolution(
							getActivity(), backCamera);
					Utils.CameraHardware.releaseCamera(backCamera);
					return video;
				}

				return video;
			}

			@Override
			protected void onPostExecute(String info) {
				if (TextUtils.isEmpty(info)) {
					info = getString(R.string.n_a);
				}
				if (isContext()) {
					infos.add(new Info(getString(R.string.video), info));
					((BaseAdapter) lv.getAdapter()).notifyDataSetChanged();
				}

				super.onPostExecute(info);
			}
		}.execute();
		infos.add(new Info(getString(R.string.led_flash), Utils.CameraHardware
				.hasCameraFlash(getActivity()) ? getString(R.string.yes)
				: getString(R.string.n_a)));
		infos.add(new Info(
				getString(R.string.auto_focus),
				Utils.CameraHardware.hasCameraAutoFocus(getActivity()) ? getString(R.string.yes)
						: getString(R.string.n_a)));
		((BaseAdapter) lv.getAdapter()).notifyDataSetChanged();

	}

	private void loadChipSet(View view) {

		ListView lv = (ListView) view
				.findViewWithTag(getString(R.string.tag_list));
		ArrayList<Info> infos = new ArrayList<Info>();

		// ((TextView) view.findViewById(R.id.tv_title))
		// .setText(cpuInfo.modelName);
		// ((TextView)
		// view.findViewById(R.id.tv_subtitle)).setText(String.format(
		// "%s core(s) %s CPU(s)", cpuInfo.cores, cpuInfo.cpus));
		infos.add(new Info(getString(R.string.chipset_), CPU.getCPUName()));
		infos.add(new Info(getString(R.string.cores_), ""
				+ CPU.getNumberCores()));
		infos.add(new Info(getString(R.string.cpus_), "" + CPU.getNumberCPUs()));
		infos.add(new Info(getString(R.string.android_ver), String.format(
				"Android %s", Build.VERSION.RELEASE)));
		infos.add(new Info(getString(R.string.kernel_arch), System
				.getProperty("os.arch")));
		infos.add(new Info(getString(R.string.kernel_ver), System
				.getProperty("os.version")));
		infos.add(new Info(getString(R.string.manufacturer), Build.MANUFACTURER));
		infos.add(new Info(getString(R.string.model), Build.MODEL));
		infos.add(new Info(getString(R.string.device), Build.DEVICE));
		infos.add(new Info(getString(R.string.product), Build.PRODUCT));
		infos.add(new Info(getString(R.string.hardware), Build.HARDWARE));
		infos.add(new Info(getString(R.string.board), Build.BOARD));
		infos.add(new Info(getString(R.string.brand), Build.BRAND));

		// infos.add(new Info("Sensor", String.format("Android %s",
		// Build.VERSION.RELEASE)));
		infos.add(new Info(getString(R.string.openssl), System
				.getProperty("android.openssl.version")));
		infos.add(new Info(getString(R.string.opengl), Utils.Hardware
				.getOPENGLVersion(getActivity().getApplicationContext())));

		infos.add(new Info(getString(R.string.bootloader), Build.BOOTLOADER));
		lv.setAdapter(new InfoAdapter(getActivity().getApplicationContext(),
				infos));

	}

	private void loadBattery(Context context, Intent intent, View view) {

		ListView lv = (ListView) view
				.findViewWithTag(getString(R.string.tag_list));
		ArrayList<Info> infos = new ArrayList<Info>();

		infos.clear();
		int health = intent.getIntExtra(BatteryManager.EXTRA_HEALTH, 0);
		String strHealth = context.getString(R.string.unknown);
		switch (health) {
		case BatteryManager.BATTERY_HEALTH_COLD:
			strHealth = context.getString(R.string.cold);
			break;
		case BatteryManager.BATTERY_HEALTH_DEAD:
			strHealth = context.getString(R.string.dead);
			break;

		case BatteryManager.BATTERY_HEALTH_GOOD:
			strHealth = context.getString(R.string.good);
			break;

		case BatteryManager.BATTERY_HEALTH_OVER_VOLTAGE:
			strHealth = context.getString(R.string.over_voltage);
			break;

		case BatteryManager.BATTERY_HEALTH_OVERHEAT:
			strHealth = context.getString(R.string.overheat);
			break;

		case BatteryManager.BATTERY_HEALTH_UNSPECIFIED_FAILURE:
			strHealth = context.getString(R.string.failure);
			break;

		default:
			break;
		}
		infos.add(new Info(getString(R.string.health), strHealth));
		int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
		infos.add(new Info(getString(R.string.level), level + " % "));
		int powerSource = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, 0);
		String strSource = context.getString(R.string.battery);
		switch (powerSource) {
		case BatteryManager.BATTERY_PLUGGED_AC:
			strSource = context.getString(R.string.ac);
			break;
		case BatteryManager.BATTERY_PLUGGED_USB:
			strSource = context.getString(R.string.usb);
			break;
		case BatteryManager.BATTERY_PLUGGED_WIRELESS:
			strSource = context.getString(R.string.wireless);
			break;
		default:
			break;
		}
		infos.add(new Info(getString(R.string.power_source), strSource));
		int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, 0);
		String strStatus = context.getString(R.string.unkown);
		switch (status) {
		case BatteryManager.BATTERY_STATUS_FULL:
			strStatus = context.getString(R.string.full);
			break;
		case BatteryManager.BATTERY_STATUS_CHARGING:
			strStatus = context.getString(R.string.charging);
			break;
		case BatteryManager.BATTERY_STATUS_DISCHARGING:
			strStatus = context.getString(R.string.discharge);
			break;
		case BatteryManager.BATTERY_STATUS_NOT_CHARGING:
			strStatus = context.getString(R.string.not_charging);
			break;
		default:
			break;
		}
		infos.add(new Info(getString(R.string.status), strStatus));

		int temp = intent.getIntExtra(BatteryManager.EXTRA_TEMPERATURE, 0);
		infos.add(new Info(getString(R.string.temperature), temp * 1f / 10
				+ getString(R.string._c)));
		int vol = intent.getIntExtra(BatteryManager.EXTRA_VOLTAGE, 0);
		infos.add(new Info(getString(R.string.voltage), vol + " mV"));
		double capacity = Utils.Battery.getBatteryCapacity(getActivity()
				.getApplicationContext());
		infos.add(new Info(getString(R.string.technology), intent
				.getStringExtra(BatteryManager.EXTRA_TECHNOLOGY)));
		if (capacity > 0) {
			infos.add(new Info(getString(R.string.capacity), String.format(
					"% .0f " + getString(R.string._ma), capacity)));
		}

		lv.setAdapter(new InfoAdapter(getActivity().getApplicationContext(),
				infos));

	}

	private void loadSensor(View view) {

		ListView lv = (ListView) view
				.findViewWithTag(getString(R.string.tag_list));
		ArrayList<Info> infos = new ArrayList<Info>();
		List<Sensor> sensors = Utils.Hardware.getAllSensors(getActivity()
				.getApplicationContext());
		for (Sensor sensor : sensors) {
			infos.add(new Info(sensor.getName().toUpperCase(Locale.ENGLISH),
					sensor.getName(), true));
			infos.add(new Info(getString(R.string.version), ""
					+ sensor.getVersion()));
			infos.add(new Info(getString(R.string.vendor), sensor.getVendor()));
			infos.add(new Info(getString(R.string.max_range), ""
					+ sensor.getMaximumRange()));
			infos.add(new Info(getString(R.string.min_delay), ""
					+ sensor.getMinDelay()));
			infos.add(new Info(getString(R.string.power), sensor.getPower()
					+ getString(R.string._ma)));
			infos.add(new Info(getString(R.string.resolution), ""
					+ sensor.getResolution()));
		}

		lv.setAdapter(new InfoAdapter(getActivity().getApplicationContext(),
				infos));

	}

	// ======================================================================
	private static class Info {
		public String name;
		public String value;
		public boolean isHiden;

		public Info(String name, String value) {
			super();
			this.name = name;
			this.value = value;
		}

		public Info(String name, String value, boolean isHiden) {
			super();
			this.name = name;
			this.value = value;
			this.isHiden = isHiden;
		}

	}

	private static class Holder {
		TextView tvName;
		TextView tvValue;
	}

	private static class InfoAdapter extends BaseAdapter {
		private Context context;
		private ArrayList<Info> infos;

		public InfoAdapter(Context context, ArrayList<Info> infos) {
			super();
			this.context = context;
			this.infos = infos;
		}

		@Override
		public int getCount() {
			return infos.size();
		}

		@Override
		public Object getItem(int position) {
			return infos.get(position);
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			Holder holder;
			Info info = infos.get(position);
			if (convertView == null) {
				convertView = LayoutInflater.from(context).inflate(
						R.layout.row_common2, null);
				holder = new Holder();
				holder.tvName = (TextView) convertView.findViewWithTag(context
						.getString(R.string.tag_name));
				holder.tvValue = (TextView) convertView.findViewWithTag(context
						.getString(R.string.tag_desc));
				convertView.setTag(holder);
			} else {
				holder = (Holder) convertView.getTag();
			}
			holder.tvName.setText(info.name);
			holder.tvValue.setText(info.value);
			holder.tvValue.setVisibility(info.isHiden ? View.GONE
					: View.VISIBLE);
			if (info.isHiden) {
				holder.tvName.setTextColor(context.getResources().getColor(
						R.color.holo_red_dark));
			} else {
				holder.tvName.setTextColor(context.getResources().getColor(
						R.color.black));
			}
			Utils.animateListView((ListView) parent, convertView, position);
			return convertView;
		}

	}

}
